#!/usr/bin/python3

# SPDX-FileCopyrightText: Red Hat, Inc.
# SPDX-License-Identifier: GPL-2.0-or-later

from __future__ import absolute_import

import argparse
import sys

from vdsm.common import cmdutils
from vdsm.common import commands

OVIRT_LOCAL_VG = "ovirt-local"


def list(args):
    out = lvm("lvs",
              "-o", "name,attr,tags,size",
              "--units", "b",
              "--nosuffix",
              "--reportformat", "json",
              "--select",
              "lv_name=\"" + args.lv_name + "\"",
              OVIRT_LOCAL_VG)
    sys.stdout.write(out.decode())


def create(args):
    cmd = ["-n", args.lv_name]
    for tag in args.addtag:
        cmd.extend(("--addtag", tag))
    if args.size:
        cmd.extend(("--size", args.size))
    if args.virtualsize:
        cmd.extend(("--virtualsize", args.virtualsize))
    if args.thinpool:
        cmd.extend(("--thinpool", args.thinpool))
    cmd.append(OVIRT_LOCAL_VG)
    lvm("lvcreate", *cmd)


def remove(args):
    lvm("lvremove", "-f", OVIRT_LOCAL_VG + "/" + args.lv_name)


def change(args):
    cmd = []
    for tag in args.addtag:
        cmd.extend(("--addtag", tag))
    for tag in args.deltag:
        cmd.extend(("--deltag", tag))
    if args.activate is not None:
        cmd.extend(("--activate", args.activate))
    cmd.append(OVIRT_LOCAL_VG + "/" + args.lv_name)
    lvm("lvchange", *cmd)


def lvm(command, *args):
    cmd = ["/usr/sbin/lvm", command]
    # Use a permissive filter to allow access on a host with a strict LVM
    # filter including only the mounted LVs.
    cmd.extend(("--config", 'devices { filter=["a|.*|"] }'))
    cmd.extend(args)
    rc, out, err = commands.execCmd(cmd, raw=True)
    if rc != 0:
        raise cmdutils.Error(cmd=cmd, rc=rc, out=out, err=err)
    return out


parser = argparse.ArgumentParser(description="oVirt local disk hook helper")
subparsers = parser.add_subparsers(title="commands")

list_parser = subparsers.add_parser("list",
                                    help="return a json with the lv "
                                         "attributes, tags, and size")
list_parser.set_defaults(command=list)
list_parser.add_argument("lv_name", help="LV name to get attributes "
                                         "tags and size")

create_parser = subparsers.add_parser("create",
                                      help="Create a LV. return nothing")
create_parser.set_defaults(command=create)
create_parser.add_argument("--addtag", action='append', help="Tags for the LV",
                           default=[])
create_parser.add_argument("--size", help="The size needed for the LV")
create_parser.add_argument("--virtualsize",
                           help="The virtual size needed for the LV")
create_parser.add_argument("--thinpool",
                           help="The thin pool the LV will be attached to")
create_parser.add_argument("lv_name", help="LV name to be created")

create_parser = subparsers.add_parser("remove",
                                      help="Remove a LV. return nothing")
create_parser.set_defaults(command=remove)
create_parser.add_argument("lv_name", help="LV name to be deleted")

change_parser = subparsers.add_parser("change",
                                      help="Update a LV. return nothing")
change_parser.set_defaults(command=change)
change_parser.add_argument("--addtag", action='append',
                           help="Tag to add on the LV", default=[])
change_parser.add_argument("--deltag", action='append',
                           help="Tag to delete from the LV", default=[])
change_parser.add_argument("--activate", help="Activate/deactivate the LV")
change_parser.add_argument("lv_name", help="LV name to be updated")

args = parser.parse_args()
args.command(args)
